package filter;

import main.Main;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.*;

/**
 * 滤镜主类，控制窗口显示和滤镜方法实现
 */
public class Repaint extends JFrame {

    BufferedImage bi_img=null;
    Graphics bg=null;
    private JToolBar toolBar;
    private JButton insertButton;
    private JButton saveButton;
    private JButton returnButton;
    private JButton button1;//灰度
    private JButton button2;//风景
    private JButton button3;//马赛克
    private JButton button4;//怀旧
    private JButton button5;//黑白
    private JButton button6;//叠图
    private JButton button7;//反色
    private static String srcImgPath = new String();
    JLabel label;
    Graphics g_get;
    private int midX,midY;
    private int lastX;
    Color backcolor = Color.white;

    /**
     * 进入滤镜package的入口
     */
    public static void filter() {
        Repaint image=new Repaint();
        image.UI();
        image.addListener();
    }

    /**
     * 滤镜主窗体
     */
    public void UI() {
        this.setTitle("滤镜");
        this.setResizable(false);
        Dimension screensize=Toolkit.getDefaultToolkit().getScreenSize();
        this.setSize(screensize.width,screensize.height-10);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //工具栏
        toolBar = new JToolBar();
        getContentPane().add(toolBar, BorderLayout.NORTH);//将工具栏放在窗体上边
        //按钮

        insertButton = new JButton("插入图片");
        insertButton.setToolTipText("插入图片");
        toolBar.add(insertButton);
        toolBar.addSeparator();

        button1 = new JButton("灰度");
        button1.setToolTipText("灰度");
        toolBar.add(button1);
        toolBar.addSeparator();

        button2 = new JButton("风景");
        button2.setToolTipText("风景");
        toolBar.add(button2);
        toolBar.addSeparator();

        button3 = new JButton("马赛克");
        button3.setToolTipText("马赛克");
        toolBar.add(button3);
        toolBar.addSeparator();

        button4 = new JButton("怀旧");
        button4.setToolTipText("怀旧");
        toolBar.add(button4);
        toolBar.addSeparator();

        button5 = new JButton("黑白");
        button5.setToolTipText("黑白");
        toolBar.add(button5);
        toolBar.addSeparator();

        button6 = new JButton("叠图");
        button6.setToolTipText("叠图");
        toolBar.add(button6);
        toolBar.addSeparator();

        button7 = new JButton("反色");
        button7.setToolTipText("反色");
        toolBar.add(button7);
        toolBar.addSeparator();

        saveButton = new JButton("保存");
        saveButton.setToolTipText("保存");
        toolBar.add(saveButton);
        toolBar.addSeparator();

        returnButton = new JButton("返回");
        returnButton.setToolTipText("返回");
        toolBar.add(returnButton);
        toolBar.addSeparator();


        this.setVisible(true);
        //获取界面的画笔，要放在界面可视之后
        g_get=this.getGraphics();
    }

    /**
     * 按钮监听器
     */
    private void addListener() {

        insertButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addPic();
            }
        });

        returnButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ret();
            }
        });

        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    if(Function.judgeNull(srcImgPath)) savePic();
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
        });

        button1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(Function.judgeNull(srcImgPath)) grey(g_get);
            }
        });
        button2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(Function.judgeNull(srcImgPath)) view(g_get);
            }
        });
        button3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(Function.judgeNull(srcImgPath)) mosaic(g_get);
            }
        });
        button4.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(Function.judgeNull(srcImgPath)) old(g_get);
            }
        });
        button5.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(Function.judgeNull(srcImgPath)) black(g_get);
            }
        });
        button6.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(Function.judgeNull(srcImgPath)) overlay(g_get);
            }
        });
        button7.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(Function.judgeNull(srcImgPath)) reverse(g_get);
            }
        });

    }

    /**
     * 插入图片
     */
    public void addPic(){
        repaint();
        //读取图片
        FileChoose image = new FileChoose();
        srcImgPath = image.openFile();
        //缩放图片
        Function.scale(srcImgPath,"tmpfiles.jpg",true, getContentPane().getWidth());
        srcImgPath="tmpfiles.jpg";

        BufferedImage img = null;
        try {
            img = ImageIO.read(new File(srcImgPath));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        getContentPane().setLayout(null);
        //设置图片
        if(label!=null) label.setIcon(new ImageIcon(img));
        else {
            label = new JLabel(new ImageIcon(img));
            getContentPane().add(label);
        }
        //将图片放在窗体左上角
//                label.setBounds(0,0,img.getWidth(),img.getHeight());
        //将图片放到窗体中间
        midX = getContentPane().getWidth() / 2 - img.getWidth() / 2;
        midY = getContentPane().getHeight() / 2 - img.getHeight() / 2;
        lastX=getContentPane().getWidth()-(int)(getContentPane().getWidth()*0.05)-img.getWidth();
        label.setBounds((int)(getContentPane().getWidth()*0.05),midY-30,img.getWidth(),img.getHeight());
//                System.out.println(img.getWidth()+"   "+img.getHeight());
    }

    /**
     * 灰度滤镜
     * @param g 原图Graphics
     */
    public void grey(Graphics g) {
        repaint();
        File file=new File(srcImgPath);
        BufferedImage bi=null;
        try {
            bi=ImageIO.read(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int w=bi.getWidth();
        int h=bi.getHeight();
        //创建一块与打开的图片一样大小的缓冲区
        bi_img=new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        //获取缓冲区的画笔
        bg=bi_img.getGraphics();
        int [][]data=new int[w][h];
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                int v=bi.getRGB(i, j);
                data[i][j]=v;
                Color c = new Color(data[i][j]);
                int r = c.getRed();
                int gr = c.getGreen();
                int b = c.getBlue();
                int change = (r + gr + b) / 3;
                c = new Color(change, change, change);
                bg.setColor(c);
                bg.drawLine(i, j, i, j);
            }
        }

        //缓冲区绘制完成后，用界面的画笔一次性将图像画出来
        g.drawImage(bi_img, lastX,midY, bi_img.getWidth(), bi_img.getHeight(), null);
        System.out.println(bi_img.getWidth()+"   "+bi_img.getHeight());
    }

    /**
     * 风景滤镜
     * @param g 原图Graphics
     */
    public void view(Graphics g) {
        repaint();
        File file=new File(srcImgPath);
        BufferedImage bi=null;
        try {
            bi=ImageIO.read(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int w=bi.getWidth();
        int h=bi.getHeight();
        //创建一块与打开的图片一样大小的缓冲区
        bi_img=new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        //获取缓冲区的画笔
        bg=bi_img.getGraphics();
        int [][]data=new int[w][h];
        for (int i = 0; i < data.length; i += 5) {
            for (int j = 0; j < data[i].length; j += 5) {
                int v=bi.getRGB(i, j);
                data[i][j]=v;
                Color color = new Color(data[i][j]);
                bg.setColor(color);
                //填充随机大小的色块
                Random ran = new Random();
                int r = ran.nextInt(20) + 5;
                bg.fillOval(i, j, r, r);
                bg.drawLine(i, j, i, j);
            }
        }

        //缓冲区绘制完成后，用界面的画笔一次性将图像画出来
        g.drawImage(bi_img, lastX,midY, bi_img.getWidth(), bi_img.getHeight(), null);
    }

    /**
     * 马赛克滤镜
     * @param g 原图Graphics
     */
    public void mosaic(Graphics g) {
        repaint();
        File file=new File(srcImgPath);
        BufferedImage bi=null;
        try {
            bi=ImageIO.read(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int w=bi.getWidth();
        int h=bi.getHeight();
        //创建一块与打开的图片一样大小的缓冲区
        bi_img=new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        //获取缓冲区的画笔
        bg=bi_img.getGraphics();
        int [][]data=new int[w][h];

        for (int i = 0; i < data.length; i += 5) {
            for (int j = 0; j < data[i].length; j += 5) {
                int v=bi.getRGB(i, j);
                data[i][j]=v;
                Color c = new Color(data[i][j]);
                bg.setColor(c);
                bg.fillRect(i, j, 8, 8);
            }
        }
        //缓冲区绘制完成后，用界面的画笔一次性将图像画出来
        g.drawImage(bi_img, lastX,midY, bi_img.getWidth(), bi_img.getHeight(), null);
    }

    /**
     * 怀旧滤镜
     * @param g 原图Graphics
     */
    public void old(Graphics g) {
        repaint();
        File file=new File(srcImgPath);
        BufferedImage bi=null;
        try {
            bi=ImageIO.read(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int w=bi.getWidth();
        int h=bi.getHeight();
        //创建一块与打开的图片一样大小的缓冲区
        bi_img=new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        //获取缓冲区的画笔
        bg=bi_img.getGraphics();
        int [][]data=new int[w][h];

        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                int v=bi.getRGB(i, j);
                data[i][j]=v;
                Color c = new Color(data[i][j]);
                int r = c.getRed();
                int gr = c.getGreen();
                int b = c.getBlue();
                // 处理溢出
                r = (int) (0.393 * r + 0.769 * gr + 0.189 * b);
                gr = (int) (0.349 * r + 0.686 * gr + 0.168 * b);
                b = (int) (0.272 * r + 0.534 * gr + 0.131 * b);
                if (r > 255)
                    r = c.getRed();
                if (gr > 255)
                    gr = c.getGreen();
                if (b > 255)
                    b = c.getBlue();
                c = new Color(r, gr, b);
                bg.setColor(c);
                bg.drawLine(i, j, i, j);
            }
        }

        //缓冲区绘制完成后，用界面的画笔一次性将图像画出来
        g.drawImage(bi_img, lastX,midY, bi_img.getWidth(), bi_img.getHeight(), null);
    }

    /**
     * 黑白滤镜
     * @param g 原图Graphics
     */
    public void black(Graphics g) {
        repaint();
        File file=new File(srcImgPath);
        BufferedImage bi=null;
        try {
            bi=ImageIO.read(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int w=bi.getWidth();
        int h=bi.getHeight();
        //创建一块与打开的图片一样大小的缓冲区
        bi_img=new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        //获取缓冲区的画笔
        bg=bi_img.getGraphics();
        int [][]data=new int[w][h];
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                int v=bi.getRGB(i, j);
                data[i][j]=v;
                Color c = new Color(data[i][j]);
                int r = c.getRed();
                int gr = c.getGreen();
                int b = c.getBlue();
                int val = (r + gr + b) / 3;
                if (val > 80) {
                    bg.setColor(Color.white);
                } else {
                    bg.setColor(Color.black);
                }
                bg.drawLine(i, j, i, j);
            }
        }
        //缓冲区绘制完成后，用界面的画笔一次性将图像画出来
        g.drawImage(bi_img, lastX,midY, bi_img.getWidth(), bi_img.getHeight(), null);
    }

    /**
     * 叠图滤镜
     * @param g 原图Graphics
     */
    public void overlay(Graphics g) {//建议先导入背景
        repaint();
        // 选取两张照片
        File file1 = new File(srcImgPath);
        FileChoose image = new FileChoose();
        Function.scale(image.openFile(),"tmpfiles2.jpg",true, getContentPane().getWidth());
        File file2 = new File("tmpfiles2.jpg");
        BufferedImage bi = null;
        BufferedImage bii = null;
        try {
            bi = ImageIO.read(file1);
            bii = ImageIO.read(file2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 取其宽高的最小值，防止数组越界
        int w = Math.min(bi.getWidth(), bii.getWidth());
        int h = Math.min(bi.getHeight(), bii.getHeight());
        // 创建一块与打开的图片一样大小的缓冲区
        bi_img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        // 获取缓冲区的画笔
        bg = bi_img.getGraphics();

        for (int i = 0; i < w; i++) {
            for (int j = 0; j < h; j++) {
                int v1 = bi.getRGB(i, j);
                int v2 = bii.getRGB(i, j);

                Color color1 = new Color(v1);
                Color color2=new Color(v2);
                // 在缓冲区中绘制图像的每个像素点
                int r=(int)(color1.getRed()*0.7+color2.getRed()*0.3);
                int gr=(int)(color1.getGreen()*0.3+color2.getGreen()*0.7);
                int b=(int)(color1.getBlue()*0.3+color2.getBlue()*0.7);
                Color color=new Color(r,gr,b);
                bg.setColor(color);
                bg.drawLine(i, j, i, j);
            }
        }
        // 缓冲区绘制完成后，用界面的画笔一次性将图像画出来
        g.drawImage(bi_img, lastX, midY, bi_img.getWidth(), bi_img.getHeight(), null);
    }

    /**
     * 反色滤镜
     * @param g
     */
    public void reverse(Graphics g){
        repaint();
        File file=new File(srcImgPath);
        BufferedImage bi=null;
        try {
            bi=ImageIO.read(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int w=bi.getWidth();
        int h=bi.getHeight();
        //创建一块与打开的图片一样大小的缓冲区
        bi_img=new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        //获取缓冲区的画笔
        bg=bi_img.getGraphics();
        int [][]data=new int[w][h];
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                int v=bi.getRGB(i, j);
                data[i][j]=v;
                Color c = new Color(data[i][j]);
                int r = c.getRed();
                int gr = c.getGreen();
                int b = c.getBlue();
                r = 255 - r;
                gr = 255 - gr;
                b = 255 - b;
                c = new Color(r, gr, b);
                bg.setColor(c);
                bg.drawLine(i, j, i, j);
            }
        }
        //缓冲区绘制完成后，用界面的画笔一次性将图像画出来
        g.drawImage(bi_img, lastX,midY, bi_img.getWidth(), bi_img.getHeight(), null);
    }

    /**
     * 保存图片
     * @throws IOException
     */
    public void savePic() throws IOException {

        JFileChooser chooser = new JFileChooser();
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int option = chooser.showSaveDialog(null);
        if (option == JFileChooser.APPROVE_OPTION) {    //假如用户选择了保存
            File file = chooser.getSelectedFile();
            try {
                BufferedImage myImage = bi_img;
                ImageIO.write(myImage, "png", file);
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }

    }

    /**
     * 返回主界面
     */
    public void ret(){
        File file1 = new File("tmpfiles.jpg");
        File file2 = new File("tmpfiles2.jpg");
        if(file1.exists())
            file1.delete();
        if(file2.exists())
            file2.delete();
        dispose();
        srcImgPath="";
        Main.returnFunc();
    }

    /**
     * 重写paint方法画图
     * @param g 原图Graphics
     */
    public void paint(Graphics g) {
        super.paint(g);
        if(bi_img!=null)g.drawImage(bi_img, lastX, midY, bi_img.getWidth(), bi_img.getHeight(), null);
    }

}

